using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using Deepcode.Flux.Core.Data;

namespace Deepcode.Flux.Core.Systems.Workflow.Bases
{
	/// <summary>
	/// Manager class for the exit actions
	/// </summary>
	public class ExitActions : BaseManager
	{
		#region Constructors
		public ExitActions() : base() { }
		public ExitActions(SqlConnection CurrentConnection) : base(CurrentConnection) { }
		public ExitActions(SqlConnection CurrentConnection, SqlTransaction CurrentTransaction) : base(CurrentConnection, CurrentTransaction) { }
		#endregion
		#region Data Retrieval
		/// <summary>
		/// Get all exit actions associated with an exit path
		/// </summary>
		/// <param name="TaskExitPathID"></param>
		/// <returns></returns>
		public ExitAction [] GetExitActionsForExitPathID(int TaskExitPathID)
		{
			DataTable results = new DataTable();

			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreWFExitActionsGetByTaskExitPath");
			da.SelectCommand.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, TaskExitPathID));
			da.Fill(results);
			ReleaseConnection();

			List<ExitAction> list = new List<ExitAction>();
			foreach (DataRow r in results.Rows)
				list.Add(new ExitAction(r));

			return list.ToArray();
		}
		/// <summary>
		/// Gets the exit action by it's path id and rank position
		/// </summary>
		/// <param name="ExitPathID"></param>
		/// <param name="RankNumber"></param>
		/// <returns></returns>
		public ExitAction GetExitActionByPathAndRank(int ExitPathID, int RankNumber)
		{
			DataTable results = new DataTable();

			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreWFExitActionsGetByTaskExitPathAndRank");
			da.SelectCommand.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, ExitPathID));
			da.SelectCommand.Parameters.Add(SQLUtility.ParameterIn("@rank", SqlDbType.Int, 4, RankNumber));
			da.Fill(results);
			ReleaseConnection();

			if( results == null ) return null;
			if( results.Rows.Count < 1 ) return null;
			return new ExitAction(results.Rows[0]);
		}
		/// <summary>
		/// Gets an exit action by it's own ID
		/// </summary>
		/// <param name="ID"></param>
		/// <returns></returns>
		public ExitAction GetExitActionsByID( int ID )
		{
			DataTable result = new DataTable();

			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreWFExitActionsGetByID");
			da.SelectCommand.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, ID));
			da.Fill(result);
			ReleaseConnection();

			if (result == null) return null;
			if (result.Rows.Count < 1) return null;

			return new ExitAction(result.Rows[0]);
		}
		#endregion
		#region Utility
		/// <summary>
		/// Gets the next available rank number
		/// </summary>
		/// <param name="ExitPathID"></param>
		/// <returns></returns>
		public int GetNextRank(int ExitPathID)
		{
			DataTable result = new DataTable();

			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreWFExitActionsGetNextRankForTaskExitPath");
			da.SelectCommand.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, ExitPathID));
			da.Fill(result);
			ReleaseConnection();

			if (result == null) return 1;
			if (result.Rows.Count < 1) return 1;

			int LastRank = SQLUtility.DBNull( result.Rows[0]["LastRank"], 0 );
			return LastRank+1;
		}
		/// <summary>
		/// Shuffles a startup action up the ranks
		/// </summary>
		/// <param name="ProcessStartID"></param>
		public void ShuffleUp(int ExitActionID)
		{
			ExitAction source = this.GetExitActionsByID(ExitActionID);
			if (source == null) return;
			if (source.Rank <= 1) return;

			ExitAction target = this.GetExitActionByPathAndRank( source.FK_ExitPathID, source.Rank - 1 );
			if (target == null) return;

			int temp = source.Rank;
			source.Rank = target.Rank;
			target.Rank = temp;

			Save(source);
			Save(target);
		}
		/// <summary>
		/// Shuffles a startup action down the ranks
		/// </summary>
		/// <param name="ProcessStartID"></param>
		public void ShuffleDown(int ExitActionID)
		{
			ExitAction source = this.GetExitActionsByID(ExitActionID);
			if (source == null) return;

			ExitAction target = this.GetExitActionByPathAndRank(source.FK_ExitPathID, source.Rank + 1);
			if (target == null) return;

			int temp = source.Rank;
			source.Rank = target.Rank;
			target.Rank = temp;

			Save(source);
			Save(target);
		}
		#endregion
		#region Save Records
		/// <summary>
		/// Save the specified exit action to the database
		/// </summary>
		/// <param name="ps"></param>
		/// <returns></returns>
		public int Save(ExitAction act)
		{
			EstablishConnection();
			SqlCommand cmd = this.CreateSqlCommand("coreWFExitActionsSave");
			SqlParameter result = SQLUtility.ParameterInOut("@id", SqlDbType.Int, 4, act.PK_ID);
			cmd.Parameters.Add(result);

			cmd.Parameters.Add( SQLUtility.ParameterIn("@FK_ExitPathID", SqlDbType.Int, 4, act.FK_ExitPathID));
			cmd.Parameters.Add( SQLUtility.ParameterIn("@Rank", SqlDbType.Int, 4, act.Rank));
			cmd.Parameters.Add( SQLUtility.ParameterIn("@Method", SqlDbType.NVarChar, 500, act.Method));
			cmd.Parameters.Add( SQLUtility.ParameterIn("@PropertyBag", SqlDbType.NText, 15, act.PropertyBag));

			cmd.ExecuteNonQuery();
			ReleaseConnection();

			if (act.PK_ID == -1)
				act.PK_ID = (int)result.Value;

			return act.PK_ID;
		}
		#endregion
		#region Delete Records
		/// <summary>
		/// Delete the specified exit action from the database
		/// </summary>
		/// <param name="ID"></param>
		/// <returns></returns>
		public bool DeleteByID(int ID)
		{
			EstablishConnection();
			SqlCommand cmd = this.CreateSqlCommand("coreWFExitActionsDeleteByID");
			cmd.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, ID));
			cmd.ExecuteNonQuery();
			ReleaseConnection();
			return true;
		}
		#endregion
	}
}
